const L = require('./lists')
const C = require('./core')

function get_between(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}

function get_one(list) {
  return L.element(list, get_between(0, list.length - 1))
}

/*
 * 从originList里随机获取一个curList中不含的元素
 * 可以设置最大尝试次数
 * 可能返回null
 */
function get_diff_element(originList, curList, maxTryTime = 10) {
  for (let i = 0; i < maxTryTime; i++) {
    let it = get_one(originList)
    if (L.is_not_in(curList, it))
      return it
  }
  return null
}

function get_no_repeat_list_fn(originList) {
  return (accList, cur) => {
    accList.push(get_diff_element(originList, accList))
    return accList
  }
}

/*
 * 作用
 * 从原始数组里获取n个彼此不同的元素
 * get_diff获取一个不同的元素，然后添加到result数组里，将result数组作为参数传到下一个get_diff里
 * 由于底层实现是有最大尝试次数的，所以返回的数组中可能含有多个null
 */
function get_no_repeat_list(originList, n) {
  const reducer = get_no_repeat_list_fn(originList)
  return new Array(n).fill().reduce(reducer, [])
}

//OK
function _get_half_no_repeat_not_null_list(vals){
    return get_no_repeat_list(vals,C.divided_fn(2)(vals.length))
             .filter(C.is_not_null)
}

//TODO: test length == 1 situatio
function get_random_map(keys, vals) {
  const curVals = _get_half_no_repeat_not_null_list(vals)
  const restVals = vals.filter(val=>L.is_not_in(curVals,val))
  const resultVals = curVals.concat(restVals)
  return C.zipmap(keys,resultVals)
}

Object.assign(exports, 
              { get_one,
                get_between, 
                get_diff_element, 
                get_no_repeat_list,
                get_random_map, })